<template>
  <div class="app-container">
	<div class="app-layout">
		<!-- 右侧文件列表 -->
		<div class="right-panel">
			<div class="pane">
			<div class="head">
					<div class="breadcrumb" >
					<div>
							<span v-if="breadcrumbList.length==0">全部文件</span>
							<el-link type="primary" v-else @click="handleBackQuery('')">全部文件</el-link>
								</div>
						<div  v-for="(item, index) in breadcrumbList" :key="item.id">
							<span class="el-breadcrumb__separator" >/</span>
							<span v-if="index === breadcrumbList.length - 1">{{ item.name }}</span>
							<el-link type="primary"  v-else  @click="handleBackQuery(item.id)">
								{{ item.name }}
							</el-link>
							</div>
						</div>
					<div class="actions" style="display: flex;">
						
						<el-button type="primary" @click="handleAddFolder" style="margin-right: 8px;">
							<el-icon><FolderAdd /></el-icon>新建文件夹
						</el-button>
						
						<el-button type="primary" @click="openUploadDialog">
							<el-icon><Upload /></el-icon>上传文件
						</el-button>
					</div>
				</div>

				<div class="body">
					<!-- 搜索栏 -->
					<div class="disk-search-bar" >
						<el-input
						  v-model="queryParams.keywords"
							placeholder="搜索文件名"
							clearable
							@keyup.enter="handleQuery"
							style="margin-right: 8px;"
						>
							<template #prefix>
								<el-icon><Search /></el-icon>
						  </template>
						</el-input>
						
						<el-radio-group v-model="viewMode" >
							<el-radio-button label="list">
								<el-icon><List /></el-icon>
							</el-radio-button>
							<el-radio-button label="grid">
								<el-icon><Grid /></el-icon>
							</el-radio-button>
						</el-radio-group>
					</div>

					<!-- 列表视图 -->
					<el-table
						v-if="viewMode === 'list'"
					  v-loading="loading"
						:data="fileList"
					  row-key="id"
						:tree-props="{
							children: 'children',
							hasChildren: 'hasChildren'
						}"
						height="calc(100vh - 280px)"
					  @selection-change="handleSelectionChange"
						@row-contextmenu="(row: DiskVO, _column: any, event: MouseEvent) => handleContextMenu(event, row)"
					>
						<el-table-column type="selection" width="55" />
						<el-table-column label="文件名" min-width="300">
							<template #default="{ row }">
								<div class="file-name" >
									<el-icon>
										<component :is="getFileIcon(row)" />
									</el-icon>
									<span @click="handleFileClick(row)" class="file-name-text">{{ row.name }}</span>
								</div>
							</template>
						</el-table-column>
						<el-table-column prop="size" label="大小" width="120">
							<template #default="{ row }">
								<div v-if="row.type!='folder'">
									{{ formatFileSize(row.size) }}
								</div>
								<div v-else>
									-
								</div>
							</template>
						</el-table-column>
						<el-table-column prop="updateTime" label="修改时间" width="180" />
						<el-table-column label="操作" width="180" fixed="right">
					    <template #default="scope">
							<el-button link type="primary" @click="handleDownload(scope.row)" v-if="scope.row.type!='folder'">
					        下载
					      </el-button>
							<el-button link type="primary" @click="handlePreview(scope.row)" v-if="scope.row.type=='folder'">
								进入
							</el-button>
							<el-button link type="primary" @click="handlePreview(scope.row)" v-else>
								进入
					      </el-button>
							<el-button link type="danger" @click="handleDelete(scope.row)">
					        删除
					      </el-button>
					    </template>
					  </el-table-column>
					</el-table>

					<!-- 网格视图 -->
					<div v-else class="grid-view">
						<el-scrollbar height="calc(100vh - 312px)" @scroll="handleScroll">
							<div v-if="fileList.length === 0 && !loading" class="empty-tip">
								<el-empty description="暂无文件" />
							</div>
							
							<div class="file-grid">
								<div
									v-for="file in fileList"
									:key="file.id"
									class="file-item"
									@click="handleFileClick(file)"
									@contextmenu.prevent="handleContextMenu($event, file)"
								>
									<div class="file-icon-wrapper">
										<el-image
											v-if="isImage(file) || isVideo(file)"
											:src="getThumbnailUrl(file)"
											:preview-src-list="[getPreviewUrl(file)]"
											fit="cover"
											class="file-thumbnail"
										/>
										<el-icon v-else class="file-icon">
											<component :is="getFileIcon(file)" />
										</el-icon>
									</div>
									<div class="file-info">
										<div class="file-name" :title="file.name">{{ file.name }}</div>
										<div class="file-meta">
											<span class="file-size" v-if="file.type=='folder'">-</span>
											<span class="file-size" v-else>{{ formatFileSize(file.size) }}</span>
											<span class="file-date">{{ formatDate(file.updateTime) }}</span>
										</div>
									</div>
								</div>
							</div>
							
							<div v-if="loading" class="loading-more">
								<el-icon class="is-loading"><Loading /></el-icon>
								<span>加载中...</span>
							</div>
							
							<div v-if="finished && fileList.length > 0" class="no-more">
								没有更多了
							</div>
						</el-scrollbar>
					</div>

					<el-pagination
						v-if="total > 0"
						:total="total"
						v-model:current-page="queryParams.page"
						v-model:page-size="queryParams.limit"
						class="pagination"
						@current-change="getFileList"
					/>
				</div>
			</div>
		</div> 
	</div>  

    <!-- 上传对话框 -->
    <el-dialog
      v-model="uploadDialog.visible"
      title="上传文件"
      width="600px"
      @close="closeUploadDialog"
    >
      <div class="upload-container">
        <el-upload
          ref="uploadRef"
          :http-request="customUpload"
          :before-upload="beforeUpload"
          :show-file-list="false"
          multiple
          drag
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>
          </div>
        </el-upload>

        <!-- 上传列表 -->
        <div class="upload-list" v-if="uploadFiles.length > 0">
          <div v-for="file in uploadFiles" :key="file.uid" class="upload-item">
            <div class="file-info">
              <span class="filename">{{ file.name }}</span>
              <span class="filesize">({{ formatFileSize(file.size) }})</span>
            </div>
            <div class="progress-info">
              <el-progress 
                :percentage="file.percentage" 
                :status="file.status === 'error' ? 'exception' : undefined"
              />
              <div class="speed-info" v-if="file.status === 'uploading' && file.speed">
                {{ formatSpeed(file.speed) }}
              </div>
            </div>
            <div class="operations">
              <el-button 
                v-if="file.status === 'error'" 
                type="primary" 
                link 
                @click="retryUpload(file)"
              >
                重试
              </el-button>
              <el-button 
                v-if="['uploading', 'error'].includes(file.status)"
                type="danger" 
                link 
                @click="cancelUpload(file)"
              >
                取消
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewDialog.visible"
      :title="previewDialog.title"
      width="80%"
      top="5vh"
    >
      <div class="preview-content">
        <!-- 图片预览 -->
        <el-image
          v-if="isImage(previewDialog.file)"
          :src="getPreviewUrl(previewDialog.file)"
          fit="contain"
          style="width: 100%; max-height: 70vh"
        />
        
        <!-- 视频预览 -->
        <video
          v-else-if="isVideo(previewDialog.file)"
          ref="videoRef"
          :src="getPreviewUrl(previewDialog.file)"
          controls
          style="width: 100%; max-height: 70vh"
          preload="metadata"
        />
        
        <!-- PDF预览 -->
        <iframe
          v-else-if="isPDF(previewDialog.file)"
          :src="getPreviewUrl(previewDialog.file)"
          style="width: 100%; height: 70vh"
        />
        
        <!-- 其他文件类型 -->
        <div v-else class="no-preview">
          <el-icon :size="48"><Document /></el-icon>
          <p>该文件类型暂不支持预览</p>
          <el-button type="primary" @click="handleDownload(previewDialog.file)">
            下载文件
          </el-button>
        </div>
      </div>
    </el-dialog>
	<DiskFolderFormDialog ref="diskFolderFormDialogRef" @closeDialog="getFileList()" />

	<!-- 右键菜单 -->
	<div 
	  v-show="contextMenuVisible" 
	  class="context-menu"
	  :style="{
		left: contextMenuPosition.x + 'px',
		top: contextMenuPosition.y + 'px'
	  }"
	>
	  <ul>
		<template v-if="currentFile?.type === 'folder'">
		  <li @click="handleAddSubFolder">
			<el-icon><FolderAdd /></el-icon>
			新建子文件夹
		  </li>
		</template>
		<template v-else>
		  <li @click="handleContextMenuDownload">
			<el-icon><Download /></el-icon>
			下载
		  </li>
		</template>
		<li @click="handleContextMenuDelete">
		  <el-icon><Delete /></el-icon>
		  删除
		</li>
	  </ul>
	</div>

	<!-- 点击空白处关闭右键菜单 -->
	<div 
	  v-show="contextMenuVisible" 
	  class="context-menu-mask" 
	  @click="closeContextMenu"
	  @contextmenu.prevent
	/>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import DiskAPI, { DiskVO } from '@/api/biz/disk';
import { getToken } from '@/utils/auth';
import DiskFolderFormDialog from './components/DiskFolderFormDialog.vue';
import { recurOptions } from "@/utils/TreeUtil";
import type { UploadRequestOptions } from 'element-plus';


// 修改自定义上传方法
const customUpload = async (options: UploadRequestOptions) => {
  const file = options.file as File;
  
  // 创建上传记录
  const uploadFile = {
    uid: Date.now().toString(),
    name: file.name,
    size: file.size,
    status: 'uploading',
    percentage: 0,
    file: file
  };
  
  uploadFiles.value.push(uploadFile);

  try {
	  console.log("queryParams=",queryParams.parentId);
    const formData = new FormData();
    formData.append('file', file);
    formData.append('parentId', currentFolderId.value || '');
	
	
	
	console.log("currentFolderId=",currentFolderId.value);

    // 获取 token
    const token = getToken();

    // 使用 XMLHttpRequest 来获取上传进度
    const xhr = new XMLHttpRequest();
    
    // 处理上传进度
    xhr.upload.onprogress = (event) => {
      if (event.lengthComputable) {
        const percentage = Math.round((event.loaded * 100) / event.total);
        // 找到对应的文件记录并更新进度
        const currentFile = uploadFiles.value.find(f => f.uid === uploadFile.uid);
        if (currentFile) {
          currentFile.percentage = percentage;
          // 计算上传速度
          const now = Date.now();
          const timeDiff = now - currentFile.lastTime;
          if (timeDiff > 0) {
            const loaded = event.loaded - (currentFile.lastLoaded || 0);
            currentFile.speed = Math.round((loaded / timeDiff) * 1000); // B/s
            currentFile.lastTime = now;
            currentFile.lastLoaded = event.loaded;
          }
        }
      }
    };

    // 创建 Promise 来处理上传
    const uploadPromise = new Promise((resolve, reject) => {
      xhr.onload = () => {
        if (xhr.status === 200) {
          try {
            const response = JSON.parse(xhr.responseText);
            resolve(response);
          } catch (error) {
            reject(new Error('解析响应失败'));
          }
        } else if (xhr.status === 401) {
          reject(new Error('登录已过期，请重新登录'));
        } else {
          reject(new Error(`上传失败: ${xhr.status}`));
        }
      };

      xhr.onerror = () => {
        reject(new Error('网络错误'));
      };

      xhr.open('POST', `${import.meta.env.VITE_APP_BASE_API}/biz/disk/upload`);
      xhr.setRequestHeader('Authorization', token);
      xhr.send(formData);
    });

    const result = await uploadPromise;
    console.log('Upload response:', result);

    if (result.code === 200) {
      // 找到对应的文件记录并更新状态
      const currentFile = uploadFiles.value.find(f => f.uid === uploadFile.uid);
      if (currentFile) {
        currentFile.status = 'success';
        currentFile.percentage = 100;
      }
      ElMessage.success('上传成功');
      getFileList();
    } else {
      throw new Error(result.msg || '上传失败');
    }
  } catch (error) {
    console.error('Upload error:', error);
    // 找到对应的文件记录并更新状态
    const currentFile = uploadFiles.value.find(f => f.uid === uploadFile.uid);
    if (currentFile) {
      currentFile.status = 'error';
    }
    ElMessage.error('上传失败：' + (error as Error).message);
  }
};

// 格式化上传速度
const formatSpeed = (speed: number) => {
  if (speed < 1024) {
    return `${speed} B/s`;
  } else if (speed < 1024 * 1024) {
    return `${(speed / 1024).toFixed(2)} KB/s`;
  } else {
    return `${(speed / (1024 * 1024)).toFixed(2)} MB/s`;
  }
};

// 修改上传文件的类型定义
interface UploadingFile {
  uid: string;
  name: string;
  size: number;
  status: 'uploading' | 'success' | 'error';
  percentage: number;
  speed?: number;
  lastTime: number;
  lastLoaded?: number;
  file: File;
}

const diskFolderFormDialogRef = ref();

// 视图模式
const viewMode = ref<'list' | 'grid'>('list');

// 查询参数
const queryParams = reactive({
  keywords: '',
  parentId: '',
  type: '',
  page: 1,
  limit: 20 // 每页加载数量
});

// 文件列表数据
const loading = ref(false);
const finished = ref(false);
const fileList = ref<any[]>([]);
const total = ref(0);
const selectedFiles = ref<DiskVO[]>([]);

// 面包屑导航
const breadcrumbList = ref<DiskVO[]>([]);

// 上传相关
const uploadRef = ref();
const uploadDialog = reactive({
  visible: false
});
const uploadFiles = ref<Array<{
  uid: string;
  name: string;
  size: number;
  status: string;
  percentage: number;
  file: File;
}>>([]);
const uploadAction = `${import.meta.env.VITE_APP_BASE_API}/biz/disk/upload/chunk`;
const uploadHeaders = {
  Authorization: (getToken())
};
const uploadData = computed(() => ({
  parentId: queryParams.parentId || ''
}));

// 添加视频引用
const videoRef = ref<HTMLVideoElement>();

// 修改预览对话框相关的响应式变量
const previewDialog = reactive({
  visible: false,
  title: '',
  file: null as DiskVO | null
});

// 监听对话框关闭
watch(() => previewDialog.visible, (newVal) => {
  if (!newVal) {
    // 对话框关闭时停止视频播放
    if (videoRef.value) {
      videoRef.value.pause();
      videoRef.value.currentTime = 0;
    }
    previewDialog.file = null;
  }
});

// 对话框状态
const dialog = reactive({
  visible: false,
  title: ''
});

// 表单数据
const formData = ref<any>({});

// 获取文件列表
const getFileList = async () => {
  loading.value = true;
  try {
    const res = await DiskAPI.getPage(queryParams);
    fileList.value = recurOptions(res.list,queryParams.parentId);
    total.value = res.totalRow;
  } catch (error) {
    console.error('获取文件列表失败:', error);
    ElMessage.error('获取文件列表失败');
  } finally {
    loading.value = false;
  }
};

// 文件操作方法
const handleSelectionChange = (selection: DiskVO[]) => {
  selectedFiles.value = selection;
};

const handleDownload = async (file: DiskVO) => {
  try {
    const res = await DiskAPI.downloadFile(file.path);
    const blob = new Blob([res]);
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = file.name;
    link.click();
    URL.revokeObjectURL(link.href);
  } catch (error) {
    console.error('下载失败:', error);
    ElMessage.error('下载失败');
  }
};

const handlePreview = (file: DiskVO) => {
  if (file.type === 'folder') {
    queryParams.parentId = file.id;
    queryParams.page = 1;
    fileList.value = [];
    finished.value = false;
    getFileList();
    updateBreadcrumb(file);
    return;
  }
  previewDialog.file = file;
  previewDialog.visible = true;
};

const handleDelete = (file: DiskVO) => {
  ElMessageBox.confirm('确认删除该文件吗？', '警告', {
    type: 'warning'
  }).then(async () => {
    try {
      await DiskAPI.deleteByIds(file.id);
      ElMessage.success('删除成功');
	  queryParams.parentId=file.parentId;
	  getFileList();
    } catch (error) {
      console.error('删除失败:', error);
      ElMessage.error('删除失败');
    }
  });
};

// 打开上传对话框
const openUploadDialog = () => {
  uploadDialog.visible = true;
};

// 关闭上传对话框
const closeUploadDialog = () => {
  uploadDialog.visible = false;
  uploadFiles.value = [];
};

// 上传前检查
const beforeUpload = (file: File) => {
  if (file.size > 1024 * 1024 * 1024 *2) {
    ElMessage.error('文件大小不能超过100MB');
    return false;
  }
  return true;
};

// 取消上传
const cancelUpload = (file: any) => {
  const index = uploadFiles.value.findIndex(f => f.uid === file.uid);
  if (index !== -1) {
    uploadFiles.value.splice(index, 1);
  }
};

// 重试上传
const retryUpload = (file: any) => {
  file.status = 'uploading';
  file.percentage = 0;
  customUpload({ file: file.file } as UploadRequestOptions);
};

// 暂停上传
const pauseUpload = (file: any) => {
  file.status = 'paused';
};

// 格式化文件大小
const formatFileSize = (size: number) => {
  if (size < 1024) {
    return size + ' B';
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + ' KB';
  } else if (size < 1024 * 1024 * 1024) {
    return (size / (1024 * 1024)).toFixed(2) + ' MB';
    } else {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
  }
};

// 添加文件类型判断方法
const isImage = (file: any) => {
  if (!file) return false;
  const imageTypes = ['image', 'jpg', 'jpeg', 'png', 'gif'];
  return imageTypes.includes(file.type?.toLowerCase()) || file.type?.toLowerCase().startsWith('image/');
};

const isVideo = (file: any) => {
  if (!file) return false;
  const videoTypes = ['video', 'mp4', 'avi', 'mov'];
  return videoTypes.includes(file.type?.toLowerCase()) || file.type?.toLowerCase().startsWith('video/');
};

const isPDF = (file: any) => {
  if (!file) return false;
  return file.type?.toLowerCase() === 'pdf' || file.type?.toLowerCase() === 'application/pdf';
};

// 获取预览URL
const getPreviewUrl = (file: any) => {
  if (!file) return '';
  return `${import.meta.env.VITE_APP_BASE_API}/biz/disk/preview?objectName=${file.path}`;
};

// 获取缩略图URL
const getThumbnailUrl = (file: any) => {
  if (!file) return '';
  return `${import.meta.env.VITE_APP_BASE_API}/biz/disk/thumbnail?objectName=${file.path}`;
};

// 获取文件图标
const getFileIcon = (file: any) => {
  if (!file) return 'Document';
  
  if (file.type === 'folder') {
    return 'Folder';
  }
  
  if (isImage(file)) {
    return 'Picture';
  }
  
  if (isVideo(file)) {
    return 'VideoCamera';
  }
  
  if (isPDF(file)) {
    return 'Document';
  }
  
  return 'Document';
};

// 格式化日期
const formatDate = (date: string) => {
  if (!date) return '';
  return new Date(date).toLocaleString();
};

// 面包屑导航
const currentFolderId=ref<string>("");
const updateBreadcrumb = (folder: DiskVO) => {
  currentFolderId.value=folder.id;
  breadcrumbList.value.push(folder);
};

// 搜索
const handleQuery = () => {
  queryParams.page = 1;
  getFileList();
};

// 返回上级目录
const handleBackQuery = (parentId: string) => {
  queryParams.page = 1;
  queryParams.parentId = parentId;
  currentFolderId.value=parentId;
  fileList.value = [];
  finished.value = false;
  
  // 更新面包屑
  if (!parentId) {
    // 如果返回根目录，清空面包屑
    breadcrumbList.value = [];
  } else {
    // 找到目标位置的索引
    const index = breadcrumbList.value.findIndex(item => item.id === parentId);
    if (index !== -1) {
      // 保留到目标位置的面包屑，移除后面的
      breadcrumbList.value = breadcrumbList.value.slice(0, index + 1);
    }
  }
  //getFileList();
  getFileList();
};

// 文件夹操作方法
const handleAddFolder = () => {
  diskFolderFormDialogRef.value?.openDialog({
    parentId: queryParams.parentId
  }, 'add');
};

// 处理右键菜单
const handleContextMenu = (event: MouseEvent, file: DiskVO) => {
  event.preventDefault();
  currentFile.value = file;
  contextMenuPosition.x = event.clientX;
  contextMenuPosition.y = event.clientY;
  contextMenuVisible.value = true;
};

// 加载更多数据
const loadMore = async () => {
  if (loading.value || finished.value) return;
      loading.value = true;
  try {
    const res = await DiskAPI.getPage(queryParams);
    if (res.list && res.list.length > 0) {
      fileList.value.push(...recurOptions(res.list, queryParams.parentId));
      queryParams.page++;
    }
    if (!res.list || res.list.length < queryParams.limit) {
      finished.value = true;
    }
  } catch (error) {
    console.error('加载文件列表失败:', error);
    ElMessage.error('加载文件列表失败');
  } finally {
    loading.value = false;
  }
};

// 处理文件点击
const handleFileClick = (file: DiskVO) => {
  if (file.type === 'folder') {
    queryParams.parentId = file.id;
    queryParams.page = 1;
    fileList.value = [];
    finished.value = false;
    loadMore();
    updateBreadcrumb(file);
  } else {
    handlePreview(file);
  }
};

// 处理滚动加载
const handleScroll = (e: any) => {
  const { scrollTop, clientHeight, scrollHeight } = e.target;
  // 滚动到底部前 50px 时加载更多
  if (scrollHeight - scrollTop - clientHeight < 50 && !loading.value && !finished.value) {
    loadMore();
  }
};

// 添加右键菜单相关的响应式变量
const contextMenuVisible = ref(false);
const contextMenuPosition = reactive({
  x: 0,
  y: 0
});
const currentFile = ref<DiskVO | null>(null);

// 下载文件
const handleContextMenuDownload = () => {
  if (!currentFile.value) return;
  handleDownload(currentFile.value);
  closeContextMenu();
};

// 删除文件/文件夹
const handleContextMenuDelete = () => {
  if (!currentFile.value) return;
  handleDelete(currentFile.value);
  closeContextMenu();
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenuVisible.value = false;
  currentFile.value = null;
};

// 在文件夹下新建子文件夹
const handleAddSubFolder = () => {
  if (!currentFile.value || currentFile.value.type !== 'folder') return;
  diskFolderFormDialogRef.value?.openDialog({
    parentId: currentFile.value.id
  }, 'add');
  closeContextMenu();
};

onMounted(() => {
  getFileList();
});
</script>
<style lang="scss" scoped>
.app-layout {
  display: flex;
  gap: 16px;
  height: 100%;
}

.left-panel {
  width: 280px;
  flex-shrink: 0;
}

.right-panel {
  flex: 1;
  min-width: 0;
}

.pane {
  background: var(--el-bg-color);
  border-radius: 4px;
  height: 100%;
		display: flex;
  flex-direction: column;
  
  .head {
    padding: 16px;
    border-bottom: 1px solid var(--el-border-color-light);
    display: flex;
    align-items: center;
		justify-content: space-between;
    .breadcrumb {
		display: flex;
		justify-content: flex-start;
		align-items: center;
    }
    
    .actions {
      margin-left: 16px;
    }
  }
  
  .body {
    flex: 1;
    padding: 16px;
    overflow: auto;
  }
}

.disk-search-bar {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  height: 40px;
  .el-input {
    width: 320px;
  }
}

.file-name {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 8px;
  
  .el-icon {
    font-size: 20px;
    color: var(--el-text-color-regular);
    flex-shrink: 0;
  }
  
  .file-name-text {
    flex: 1;
    min-width: 0;
    cursor: pointer;
    color: var(--el-text-color-regular);
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    
    &:hover {
      color: var(--el-color-primary);
    }
  }
}

.grid-view {
  padding: 16px;
  
  .file-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
  }
  
  .file-item {
    display: flex;
    align-items: center;
    padding: 8px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    background: var(--el-bg-color-overlay);
    border: 1px solid var(--el-border-color-lighter);
    
    &:hover {
      background: var(--el-color-primary-light-9);
      border-color: var(--el-color-primary-light-7);
    }
    
    .file-icon-wrapper {
      width: 40px;
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 12px;
      flex-shrink: 0;
      
      .file-thumbnail {
        width: 100%;
        height: 100%;
        border-radius: 4px;
        object-fit: cover;
      }
      
      .file-icon {
        font-size: 24px;
        color: var(--el-text-color-regular);
      }
    }
    
    .file-info {
      flex: 1;
      min-width: 0;
      
      .file-name {
        font-size: 14px;
        margin-bottom: 4px;
        color: var(--el-text-color-primary);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      
      .file-meta {
        display: flex;
        justify-content: space-between;
		font-size: 12px;
        color: var(--el-text-color-secondary);
        
        .file-size {
          margin-right: 8px;
        }
      }
    }
  }
}

.loading-more,
.no-more {
  text-align: center;
  padding: 12px;
  color: var(--el-text-color-secondary);
  font-size: 13px;
}

.empty-tip {
  padding: 40px 0;
}

.preview-content {
		display: flex;
		justify-content: center;
		align-items: center;
  min-height: 400px;
  
  .no-preview {
    text-align: center;
    color: var(--el-text-color-secondary);
    
    .el-icon {
      margin-bottom: 16px;
    }
  }
}

.pagination {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}

.context-menu {
  position: fixed;
  z-index: 2000;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-light);
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
  min-width: 160px;
  
  ul {
    margin: 0;
    padding: 4px 0;
    list-style: none;
    
    li {
      padding: 8px 16px;
      display: flex;
      align-items: center;
      gap: 8px;
		cursor: pointer;
      color: var(--el-text-color-regular);
      font-size: 14px;
      
      &:hover {
        background-color: var(--el-color-primary-light-9);
        color: var(--el-color-primary);
      }
      
      .el-icon {
        font-size: 16px;
      }
    }
  }
}

.context-menu-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1999;
}

// 修改列表视图相关样式
:deep(.el-table) {
  // 表头样式
  .el-table__header {
    th {
      background-color: var(--el-fill-color-light);
      color: var(--el-text-color-regular);
      font-weight: 500;
      height: 40px;
      
      &.is-leaf {
        border-bottom: 1px solid var(--el-border-color-lighter);
      }
    }
  }
  
  // 表格行样式
  .el-table__row {
    height: 50px;
    
    &:hover {
      td {
        background-color: var(--el-color-primary-light-9) !important;
      }
    }
    
    td {
      padding: 8px 0;
      border-bottom: 1px solid var(--el-border-color-lighter);
    }
  }
  
  // 树形图标样式
  .el-table__expand-icon {
    color: var(--el-text-color-secondary);
    
    &:hover {
      color: var(--el-color-primary);
    }
    
    .el-icon {
      font-size: 12px;
    }
  }
  
  // 选择框样式
  .el-checkbox {
    margin-right: 8px;
  }
}

// 操作列样式
:deep(.el-button--link) {
  height: 28px;
  padding: 0 8px;
  
  &:not(:last-child) {
    margin-right: 8px;
    border-right: 1px solid var(--el-border-color-lighter);
  }
}

:deep(.cell){
	display: flex;
	align-items: center;
}

.upload-container {
  .upload-list {
    margin-top: 20px;
    max-height: 300px;
    overflow-y: auto;
    
    .upload-item {
      padding: 10px;
      border-bottom: 1px solid var(--el-border-color-lighter);
      
      &:last-child {
        border-bottom: none;
      }
      
      .file-info {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 8px;
        
        .filename {
          flex: 1;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        
        .filesize {
          color: var(--el-text-color-secondary);
          font-size: 12px;
        }
      }
      
      .progress-info {
        margin-bottom: 8px;
        
        .speed-info {
          margin-top: 4px;
          font-size: 12px;
          color: var(--el-text-color-secondary);
        }
        
        .status-text {
          font-size: 12px;
          
          &.success {
            color: var(--el-color-success);
          }
          
          &.error {
            color: var(--el-color-danger);
          }
          
          &.paused {
            color: var(--el-color-warning);
          }
        }
      }
      
      .operations {
        display: flex;
        justify-content: flex-end;
        gap: 8px;
      }
    }
  }
	}
</style>